package com.itheima.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.itheima.bcript.BCryptUtil;
import com.itheima.exception.PasswordErrorException;
import com.itheima.exception.UsernameNotFoundException;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.dto.EmpQuery;
import com.itheima.pojo.entity.Dept;
import com.itheima.pojo.entity.Emp;
import com.itheima.pojo.entity.EmpExpr;
import com.itheima.pojo.entity.EmpLog;
import com.itheima.pojo.vo.PageResult;
import com.itheima.service.DeptService;
import com.itheima.service.EmpLogService;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class EmpServiceImpl extends ServiceImpl<EmpMapper,Emp> implements EmpService {

    @Autowired private EmpExprMapper empExprMapper;
    @Autowired private EmpLogService empLogService;
    @Autowired
    private BCryptUtil bCryptUtil;
    @Autowired
    private DeptService deptService;

    @Override
    public PageResult page(EmpQuery empQuery) {
        Page<Emp> page = Page.of(empQuery.getPage(),empQuery.getPageSize());
        //page.addOrder(OrderItem.desc("update_time"));
        LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper .like(empQuery.getName()!=null&& !empQuery.getName().isEmpty(),Emp::getName,empQuery.getName())
                .eq(empQuery.getGender()!=null,Emp::getGender,empQuery.getGender())
                .between(empQuery.getBegin()!=null&&empQuery.getEnd()!=null,Emp::getEntryDate,empQuery.getBegin(),empQuery.getEnd())
                .orderByDesc(Emp::getUpdateTime);

        page=page(page,queryWrapper);

        List<Emp> emps = page.getRecords();
        List<Integer> depts = emps.stream().map(Emp::getDeptId).collect(Collectors.toList());

        if(!CollectionUtil.isEmpty(depts)) {
            List<Dept> deptList = deptService.listByIds(depts);
            for (Emp emp : emps) {
                for (Dept dept : deptList) {
                    if(emp.getDeptId()!=null && emp.getDeptId().equals(dept.getId())){
                        emp.setDeptName(dept.getName());
                    }
                }
            }
        }

        return new PageResult(page.getTotal(),page.getRecords());

        /*// 开启分页
        PageHelper.startPage(empQuery.getPage(), empQuery.getPageSize());
        //执行查询
        List<Emp> empList = empMapper.page(empQuery);
        Page< Emp> pageList = (Page< Emp>) empList;
        return new PageResult(pageList.getTotal(), pageList.getResult());*/
    }

    @Override

    public Emp findById(Integer id) {
        Emp emp = getById(id);
        List<EmpExpr> empExprList = empExprMapper.selectList(new LambdaQueryWrapper<EmpExpr>().eq(EmpExpr::getEmpId, emp.getId()));
        emp.setExprList(empExprList);
        //Emp emp = empMapper.findById(id);
        return emp;
    }

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @Override
    public void saveEmp(Emp emp) {
        try {
            log.info("执行保存员工数据emp:{}",emp);
            String password = bCryptUtil.hashPassword("123456");
            emp.setPassword(password);
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            //empMapper.insert(emp);
            save(emp);
            List<EmpExpr> exprList = emp.getExprList();
            Integer empId = emp.getId();
            if(exprList != null && !exprList.isEmpty()){
                for (EmpExpr expr : exprList) {
                    expr.setEmpId(empId);
                }
                empExprMapper.insert(exprList);
            }

        } finally {
            empLogService.insertLog(new EmpLog(emp.getId(),LocalDateTime.now(),emp.getName()+"新增员工数据"));
        }
    }

    @Override
    public List<Emp> findAll() {
        List<Emp> empList = list();

        //return empMapper.findAll();
        return empList;
    }

    @Transactional
    @Override
    public void updateEmp(Emp emp) {
        log.info("执行更新员工数据emp:{}",emp);
        //emp.setUpdateTime(LocalDateTime.now());
        //更新员工数据
        updateById(emp);
        Integer id = emp.getId();
        //empExprMapper.deleteByEmpId(Arrays.asList(id));
        LambdaQueryWrapper<EmpExpr> queryWrapper = new LambdaQueryWrapper<EmpExpr>();
        queryWrapper.in(EmpExpr::getEmpId, Arrays.asList(id));
        empExprMapper.delete(queryWrapper);
        List<EmpExpr> exprList = emp.getExprList();
        if(!CollectionUtil.isEmpty(exprList)){
            exprList.forEach(expr->expr.setEmpId(emp.getId()));
            empExprMapper.insert(exprList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<Integer> ids) {
        removeBatchByIds(ids);
        List<EmpExpr> empExprList = empExprMapper.selectList(new LambdaQueryWrapper<EmpExpr>().in(EmpExpr::getEmpId, ids));
        if(empExprList != null && !empExprList.isEmpty()){
            empExprMapper.delete(new LambdaQueryWrapper<EmpExpr>().in(EmpExpr::getEmpId, ids));
        }
    }

    @Override
    public Emp checkLogin(Emp emp) {
        //Emp loginEmp = empMapper.selUsernameAndPassword(emp.getUsername());
        Emp loginEmp = this.getOne(new LambdaQueryWrapper<Emp>().in(Emp::getUsername, emp.getUsername()));
        if(loginEmp==null){
            throw new UsernameNotFoundException("用户名不存在！");
        }
        /*if(!Objects.equals(loginEmp.getPassword(),emp.getPassword())){
            throw new PasswordErrorException("密码错误！");
        }*/
        if(!bCryptUtil.checkPassword(emp.getPassword(),loginEmp.getPassword())){
            throw new UsernameNotFoundException("密码错误！");
        }

        return loginEmp;
    }
}
